home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume30 / mserv-3.0 / part03 < prev    next >
Encoding:
Text File  |  1992-06-19  |  54.6 KB  |  2,056 lines

  1. Newsgroups: comp.sources.misc
  2. From: jv@mh.nl (Johan Vromans)
  3. Subject:  v30i048:  mserv-3.0 - Squirrel Mail Server Software, Part03/04
  4. Message-ID: <1992Jun14.005911.18854@sparky.imd.sterling.com>
  5. X-Md4-Signature: c7d54ea4eab2114ecfa9b1287414bf36
  6. Date: Sun, 14 Jun 1992 00:59:11 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jv@mh.nl (Johan Vromans)
  10. Posting-number: Volume 30, Issue 48
  11. Archive-name: mserv-3.0/part03
  12. Environment: Perl
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  19. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  20. # Contents:  Makefile do_report.pl dr_pack.pl dr_uucp.pl makeindex.pl
  21. #   ms_lock.pl mserv_common.pl pr_doindex.pl pr_dowork.pl
  22. #   pr_dsearch.pl pr_isearch.pl report.pl rfc822.pl testlock.pl
  23. # Wrapped by kent@sparky on Sat Jun 13 19:46:22 1992
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 3 (of 4)."'
  27. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'Makefile'\"
  29. else
  30.   echo shar: Extracting \"'Makefile'\" \(4519 characters\)
  31.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  32. X# Makefile -- for mail server
  33. X# SCCS Status     : %Z%@ %M%    %I%
  34. X# Author          : Johan Vromans
  35. X# Created On      : Fri May  1 15:44:47 1992
  36. X# Last Modified By: Johan Vromans
  37. X# Last Modified On: Wed Jun 10 14:24:51 1992
  38. X# Update Count    : 69
  39. X# Status          : 
  40. X
  41. XSHELL    = /bin/sh
  42. XCC    = gcc -Wall
  43. XCFLAGS    = -O
  44. X
  45. X# Perl 4.019 or later
  46. XPERL    = /usr/local/bin/perl
  47. X# Where programs and files reside.
  48. XLIBDIR    = /usr/local/lib/mserv
  49. X# Where help data will be installed.
  50. XPUBDIR    = $(LIBDIR)/pub
  51. X# The owner of the mail server files
  52. XSERVER    = mserv
  53. X
  54. X# Perl scripts that will be public executable.
  55. XPEARLS    = process dorequest unpack makeindex chkconfig report do_report
  56. X# Misc. files.
  57. XFILES    = rfc822.pl mserv_common.pl \
  58. X    ms_lock.pl \
  59. X    dr_mail.pl dr_uucp.pl dr_pack.pl \
  60. X    pr_isearch.pl pr_dsearch.pl pr_doindex.pl pr_dowork.pl
  61. X# Config data. Will not replace existing files.
  62. XCONFIG    = mserv_config.pl mserv.hints mserv.notes
  63. X# Public executable shell scripts.
  64. XSHELLS    = do_runq
  65. X# These files will be created, if needed
  66. XTOUCH    = logfile lockfile queue .errrun
  67. X# Public services.
  68. XAIDS    = HELP unpack.pl
  69. X
  70. Xall:    $(PEARLS) mlistener
  71. X    @echo "Use \"make listener\" to generate the listener program"
  72. X    @echo "Use \"make ixlookup\" if you selected index lookup"
  73. X
  74. X$(PEARLS) mlistener:
  75. X    @for prog in $(PEARLS) mlistener; do \
  76. X        echo "Preparing $$prog..."; \
  77. X        rm -f $$prog; \
  78. X        sed -e '1s|/usr/local/bin/perl|$(PERL)|' \
  79. X            -e 's|/usr/local/lib/mserv|$(LIBDIR)|' \
  80. X            $$prog.pl >$$prog; \
  81. X    done
  82. X
  83. Xinstall: $(PEARLS)
  84. X    -mkdir $(LIBDIR)
  85. X    @for prog in $(PEARLS); do \
  86. X        echo "Installing $$prog..."; \
  87. X        install -m 0555 $$prog $(LIBDIR)/$$prog; \
  88. X    done
  89. X    @for prog in $(SHELLS); do \
  90. X        echo "Installing $$prog..."; \
  91. X        install -c -m 0555 $$prog.sh $(LIBDIR)/$$prog; \
  92. X    done
  93. X    @for prog in $(FILES); do \
  94. X        echo "Installing $$prog..."; \
  95. X        install -c -m 0444 $$prog $(LIBDIR); \
  96. X    done
  97. X    @for prog in $(TOUCH); do \
  98. X        if [ -f $(LIBDIR)/$$prog ]; then \
  99. X        true; \
  100. X        else \
  101. X        echo "Creating $$prog..."; \
  102. X        cat < /dev/null > $(LIBDIR)/$$prog; \
  103. X        fi; \
  104. X    done
  105. X    @for prog in $(CONFIG); do \
  106. X        if [ -f $(LIBDIR)/$$prog ]; then \
  107. X        echo "Installing $$prog as NEW-$$prog..."; \
  108. X        echo "IMPORTANT: Update $$prog by hand if needed!"; \
  109. X        install -c -m 0644 $$prog $(LIBDIR)/NEW-$$prog; \
  110. X        else \
  111. X        echo "Installing $$prog..."; \
  112. X        install -c -m 0644 $$prog $(LIBDIR); \
  113. X        fi \
  114. X    done
  115. X    -mkdir $(PUBDIR)
  116. X    @for prog in $(AIDS); do \
  117. X        echo "Installing $$prog in $(PUBDIR)..."; \
  118. X        install -c -m 0444 $$prog $(PUBDIR)/$$prog; \
  119. X    done
  120. X    -(cd $(PUBDIR); rm -f help; ln HELP help)
  121. X    @echo "Use \"make install-listener\" to install the listener program"
  122. X    @echo "Use \"make install-ixlookup\" to install the ixlookup program"
  123. X
  124. X################ Listener ################
  125. X
  126. Xlistener: mlistener
  127. X    rm -f listener listener.c
  128. X    $(PERL) mlistener -verbose > listener.c
  129. X    $(CC) $(CFLAGS) -o listener listener.c
  130. X
  131. X# Install setuid to the installer...
  132. Xinstall-listener:    listener
  133. X    rm -f $(LIBDIR)/listener
  134. X    install -s -c listener $(LIBDIR)/listener
  135. X    chmod -w,+x,u+s $(LIBDIR)/listener
  136. X
  137. X################ ixlookup ################
  138. X
  139. X# ixlookup is based on GNU find/locate.
  140. X# If you have GNU find 3.6 or later, you can use the locate program.
  141. X# For locate 3.5, a patch is available to create a customized version
  142. X# of this program. "make ixlookup" will build it.
  143. X# Set GNUFIND to indicate where the source of GNU locate, includes
  144. X# and find lib can be found.
  145. X# Reference version is GNU find 3.5.
  146. XGNUFIND = /beethoven/arch/GNU/find-3.5
  147. X
  148. Xixlookup.c: $(GNUFIND)/locate/locate.c ixlookup.patch
  149. X    rm -f ixlookup.c
  150. X    cp  $(GNUFIND)/locate/locate.c ixlookup.c
  151. X    patch -p0 -N < ixlookup.patch
  152. X
  153. Xixlookup:    ixlookup.c
  154. X    rm -f ixlookup
  155. X    $(CC) $(CFLAGS) '-DFCODES="$(LIBDIR)/find.codes"' \
  156. X        -I$(GNUFIND)/lib -o ixlookup ixlookup.c \
  157. X        $(GNUFIND)/lib/libfind.a
  158. X
  159. Xinstall-ixlookup:    ixlookup
  160. X    install -s -m 0555 -c ixlookup $(LIBDIR)
  161. X
  162. X################ Cleanup ################
  163. X
  164. Xclean:
  165. X    rm -f *~ core a.out $(PEARLS) mlistener listener listener.c \
  166. X    *.orig *.rej ixlookup.c ixlookup
  167. X
  168. X################ Maintenance ################
  169. X
  170. Xtar.Z:;    pdtar -zcv -T MANIFEST -f mserv.tar.Z
  171. X
  172. Xdiffs:
  173. X    rm -f mserv.diffs
  174. X    -while read file junk; do \
  175. X        diff -c dist/$$file $$file >> mserv.diffs; \
  176. X    done < MANIFEST
  177. X    compress < mserv.diffs > mserv.DZ
  178. X
  179. XAUX   = Makefile mserv_config.pl ChangeLog* Misc
  180. XTZ:;    tar cvf - $(AUX) SCCS | compress > mserv.TZ
  181. X
  182. Xshar:
  183. X    rm -f mserv-*.shar.*
  184. X    shar -p -f -F \
  185. X        -L 30 -o mserv-3.0.shar \
  186. X        -a -n mserv-3.0.shar -s 'Johan Vromans <jv@mh.nl>' \
  187. X        -S < MANIFEST
  188. X    ls -l mserv-*.shar.*
  189. X
  190. END_OF_FILE
  191.   if test 4519 -ne `wc -c <'Makefile'`; then
  192.     echo shar: \"'Makefile'\" unpacked with wrong size!
  193.   fi
  194.   # end of 'Makefile'
  195. fi
  196. if test -f 'do_report.pl' -a "${1}" != "-c" ; then 
  197.   echo shar: Will not clobber existing file \"'do_report.pl'\"
  198. else
  199.   echo shar: Extracting \"'do_report.pl'\" \(4485 characters\)
  200.   sed "s/^X//" >'do_report.pl' <<'END_OF_FILE'
  201. X#!/usr/local/bin/perl
  202. X# do_report.pl -- run mail server report
  203. X# SCCS Status     : @(#)@ do_report    1.5
  204. X# Author          : Johan Vromans
  205. X# Created On      : Sat May  2 14:15:16 1992
  206. X# Last Modified By: Johan Vromans
  207. X# Last Modified On: Sat May  9 00:00:17 1992
  208. X# Update Count    : 33
  209. X# Status          : OK
  210. X
  211. X$my_name = "do_report";
  212. X$my_version = "1.5";
  213. X#
  214. X################ Common stuff ################
  215. X
  216. X$libdir = $ENV{"MSERVLIB"} || "/usr/local/lib/mserv";
  217. Xunshift (@INC, $libdir);
  218. Xrequire "mserv_common.pl";
  219. X
  220. X################ Presets ################
  221. X
  222. X@args = ();
  223. X@dest = ( $mserv_owner );
  224. X
  225. X################ Options handling ################
  226. X
  227. X&options if @ARGV > 0 && $ARGV[0] =~ /^-+[^-]+/;
  228. Xprint ($my_package, " [", $my_name, " ", $my_version, "]\n")
  229. X    if $opt_ident;
  230. X@dest = @ARGV if @ARGV > 0;
  231. X
  232. X################ Main ################
  233. X
  234. X$tmpfile_prefix = "/usr/tmp/rpt$$.";
  235. X$rpt = $tmpfile_prefix . "rpt";
  236. X$err = $tmpfile_prefix . "err";
  237. X$oldlog = $logfile . ".o";
  238. X
  239. Xif ( $opt_collect ) {
  240. X    # Seize logfile.
  241. X    &die ("Found $oldlog, will not proceed") if -s $oldlog;
  242. X    &unlink ($oldlog);
  243. X
  244. X    if ( &rename ($logfile, $oldlog) ) {
  245. X    open (LOG, ">".$logfile) && close (LOG);
  246. X    }
  247. X    else {
  248. X    &die ("Cannot rename $logfile to $oldlog [$!]");
  249. X    }
  250. X
  251. X    # Run report.
  252. X    &system ("$libdir/report @args $oldlog >$rpt 2>$err");
  253. X}
  254. Xelse {
  255. X    &system ("$libdir/report @args >$rpt 2>$err");
  256. X}
  257. X
  258. Xif ( $opt_collect ) {
  259. X
  260. X    # Append to accumulating data and compress (again).
  261. X    if ( -f $logfile . ".cum.Z") {
  262. X    &system ("uncompress $logfile.cum");
  263. X    &system ("cat $oldlog >> $logfile.cum");
  264. X    &unlink ($oldlog);
  265. X    &system ("compress $logfile.cum");
  266. X    }
  267. X    else {
  268. X    &system ("cat $oldlog >> $logfile.cum");
  269. X    &unlink ($oldlog);
  270. X    # &system ("compress $logfile.cum");
  271. X    }
  272. X}
  273. X
  274. X&cleanup;
  275. X
  276. X################ Subroutines ################
  277. X
  278. Xsub cleanup {
  279. X    &mail ($err, "ERRORS from Mail Server") if -s $err;
  280. X    &mail ($rpt, "Mail Server Report") if -s $rpt;
  281. X    &unlink ($rpt, $err);
  282. X}
  283. X
  284. Xsub unlink {
  285. X    local (@files) = @_;
  286. X    print STDERR ("+ unlink @files\n") if $opt_trace;
  287. X    unlink (@files);
  288. X}
  289. X
  290. Xsub rename {
  291. X    local ($old, $new) = @_;
  292. X    print STDERR ("+ rename $old $new\n") if $opt_trace;
  293. X    rename ($old, $new);
  294. X}
  295. X
  296. Xsub system {
  297. X    local ($cmd) = (@_);
  298. X    local ($ret);
  299. X    print STDERR ("+ $cmd\n") if $opt_trace;
  300. X    $ret = system ($cmd);
  301. X    &die (sprintf ("Return 0x%x from \"$cmd\"", $ret))
  302. X    unless $ret == 0;
  303. X    $ret;
  304. X}
  305. X
  306. Xsub warn {
  307. X    local ($msg) = (@_);
  308. X    warn ($my_name . ": " . $msg . "\n");
  309. X}
  310. X
  311. Xsub die {
  312. X    &warn;
  313. X    &cleanup;
  314. X    exit (1);
  315. X}
  316. X
  317. Xsub mail {
  318. X    local ($file, $subj) = @_;
  319. X    local ($cmd) = "$sendmail '" . join("' '", @dest) . "'";
  320. X
  321. X    # DO NOT USE '&die' in this routine.
  322. X
  323. X    print STDERR ("+ |", $cmd, "\n") if $opt_trace;
  324. X
  325. X    open (MAIL, "|" . $cmd)
  326. X    || die ("$my_name: Cannot invoke $cmd [$!]\n");
  327. X    print MAIL ("To: ", join(", ", @dest), "\n",
  328. X        "Subject: $subj\n",
  329. X        "\n");
  330. X    if ( open (FILE, $file) ) {
  331. X    while ( <FILE> ) {
  332. X        print MAIL $_;
  333. X    }
  334. X    close (FILE);
  335. X    }
  336. X    close (MAIL);
  337. X    die ("$my_name: Mail error $?\n") if $?;
  338. X}
  339. X
  340. Xsub options {
  341. X    require "newgetopt.pl";
  342. X    $opt_ident = $opt_help = 0;
  343. X    $opt_errors = $opt_usage = $opt_full = 0;
  344. X    $opt_collect = $opt_trace = $opt_noupdate = 0;
  345. X    if ( !&NGetOpt ("ident", "errors", "usage", "full", "collect",
  346. X            "since=s", "noupdate",
  347. X            "trace", "help")
  348. X    || $opt_help ) {
  349. X    &usage;
  350. X    }
  351. X    $opt_errors |= $opt_full;
  352. X    $opt_usage |= $opt_full;
  353. X    $opt_usage = 1 unless $opt_errors;
  354. X    unshift (@args, "-full") if $opt_usage && $opt_errors;
  355. X    unshift (@args, "-errors") if $opt_errors && !$opt_usage;
  356. X    unshift (@args, "-since", $opt_since) if defined $opt_since;
  357. X    unshift (@args, "-noupdate") if $opt_noupdate;
  358. X    unshift (@args, "-usage") if $opt_usage && !$opt_errors;
  359. X    undef $opt_errors, $opt_full, $opt_usage;
  360. X}
  361. X
  362. Xsub usage {
  363. X    print STDERR <<EndOfUsage;
  364. X$my_package [$my_name $my_version]
  365. X
  366. XUsage: $my_name [options] [ recipients... ]
  367. X
  368. XOptions:
  369. X    -usage    generate usage report to STDOUT
  370. X    -full    generate usage report and error report
  371. X    -collect    collect and cleanup logfile data
  372. X    -since FILE    only error messages newer than FILE
  373. X        (FILE date will be updated upon successful completion)
  374. X    -noupdate    do not update FILE date
  375. X    -help    this message
  376. X    -trace    show commands
  377. X    -ident    print identification
  378. X
  379. XDefault action is to generate a usage report, and to mail it to the
  380. Xrecipients (default: $mserv_owner).
  381. XEndOfUsage
  382. X    exit (1);
  383. X}
  384. END_OF_FILE
  385.   if test 4485 -ne `wc -c <'do_report.pl'`; then
  386.     echo shar: \"'do_report.pl'\" unpacked with wrong size!
  387.   fi
  388.   # end of 'do_report.pl'
  389. fi
  390. if test -f 'dr_pack.pl' -a "${1}" != "-c" ; then 
  391.   echo shar: Will not clobber existing file \"'dr_pack.pl'\"
  392. else
  393.   echo shar: Extracting \"'dr_pack.pl'\" \(2769 characters\)
  394.   sed "s/^X//" >'dr_pack.pl' <<'END_OF_FILE'
  395. X# dr_pack.pl -- handle packing
  396. X# SCCS Status     : @(#)@ dr_pack.pl    3.1
  397. X# Author          : Johan Vromans
  398. X# Created On      : Thu Jun  4 22:22:49 1992
  399. X# Last Modified By: Johan Vromans
  400. X# Last Modified On: Thu Jun  4 23:07:22 1992
  401. X# Update Count    : 6
  402. X# Status          : OK
  403. X
  404. Xsub pack_mail_request {
  405. X    local ($rcpt, $dest, $request, $file, $coding, $limit, $packing, $parts) = @_;
  406. X
  407. X    if ( $opt_debug ) {
  408. X    print STDERR ("&pack_mail_request(rcpt=$rcpt, address=$dest, ",
  409. X              "request=$request,\n",
  410. X              "    file=$file,\n",
  411. X              "    limit=$limit, packing=$packing, parts=$parts)\n");
  412. X    }
  413. X
  414. X    ($request, $file) = &packing ($request, $file, $packing);
  415. X    require "$libdir/dr_mail.pl";
  416. X    &mail_request ($rcpt, $dest, $request, $file, $coding, $limit, $parts);
  417. X    unlink ($file) unless $opt_keep;
  418. X}
  419. X
  420. Xsub pack_uucp_request {
  421. X    local ($rcpt, $uupath, $uunote, $request, $file, $limit, $packing, $parts) = @_;
  422. X
  423. X    if ( $opt_debug ) {
  424. X    print STDERR ("&pack_uucp_request(rcpt=$rcpt, uupath=$uupath,\n",
  425. X              "    uunote=$uunote, request=$request,\n",
  426. X              "    file=$file,\n",
  427. X              "    limit=$limit, oacking=$packing, parts=$parts)\n");
  428. X    }
  429. X
  430. X    ($request, $file) = &packing ($request, $file, $packing);
  431. X    require "$libdir/dr_uucp.pl";
  432. X    &uucp_request ($rcpt, $uupath, $uunote, $request, $file, $limit, $parts);
  433. X    unlink ($file) unless $opt_keep;
  434. X}
  435. X
  436. Xsub packing {
  437. X    local ($request, $file, $packing) = @_;
  438. X
  439. X    # Packs the files in directory $file into an $packing-archive, and
  440. X    # returns an array containing the modified name of the request
  441. X    # and the name of the archive file.
  442. X
  443. X    &check_file ($file, 1);
  444. X
  445. X    local ($dir, $realname) = &fnsplit ($file);
  446. X    local ($tmpfile_prefix) = $opt_keep || "$tmpdir/pck$$.";
  447. X    local ($cmd) = "$find $realname -follow -type f ! -name '.*' -print | ";
  448. X
  449. X    chdir $dir || &die ("Cannot chdir to $dir [$!]");
  450. X
  451. X    if ( $packing eq "tar" ) {
  452. X    $file = $tmpfile_prefix . "tar.Z";
  453. X    $cmd .= $pdtar ? "$pdtar -z -c -h -T - -f $file"
  454. X        : "$tar -c -h -T - -f - | $compress > $file";
  455. X    &system ($cmd);
  456. X    &die ("Problem executing \"$cmd\"") unless -s $file;
  457. X    return ($request . "-tar.Z", $file);
  458. X    }
  459. X
  460. X    if ( $packing eq "zoo" ) {
  461. X    $file = $tmpfile_prefix . "zoo";
  462. X    $cmd .= "$zoo aIqq $file";
  463. X    &system ($cmd);
  464. X    &die ("Problem executing \"$cmd\"") unless -s $file;
  465. X    return ($request . "-zoo", $file);
  466. X    }
  467. X
  468. X    if ( $packing eq "zip" ) {
  469. X    $file = $tmpfile_prefix . "zip";
  470. X    # It is not really necessary to use find for zip,
  471. X    # but this is the only way to exclude .-files.
  472. X    $cmd .= "$zip -n -q -b $tmpdir $file -";
  473. X    &system ($cmd);
  474. X    &die ("Problem executing \"$cmd\"") unless -s $file;
  475. X    return ($request . "-zip", $file);
  476. X    }
  477. X
  478. X    &die ("Invalid packing code in queue");
  479. X    (undef, undef);
  480. X}
  481. X
  482. X1;
  483. END_OF_FILE
  484.   if test 2769 -ne `wc -c <'dr_pack.pl'`; then
  485.     echo shar: \"'dr_pack.pl'\" unpacked with wrong size!
  486.   fi
  487.   # end of 'dr_pack.pl'
  488. fi
  489. if test -f 'dr_uucp.pl' -a "${1}" != "-c" ; then 
  490.   echo shar: Will not clobber existing file \"'dr_uucp.pl'\"
  491. else
  492.   echo shar: Extracting \"'dr_uucp.pl'\" \(2794 characters\)
  493.   sed "s/^X//" >'dr_uucp.pl' <<'END_OF_FILE'
  494. X# dr_uucp.pl -- handle request via uucp
  495. X# SCCS Status     : @(#)@ dr_uucp.pl    3.1
  496. X# Author          : Johan Vromans
  497. X# Created On      : Thu Jun  4 22:22:49 1992
  498. X# Last Modified By: Johan Vromans
  499. X# Last Modified On: Thu Jun  4 23:07:07 1992
  500. X# Update Count    : 4
  501. X# Status          : OK
  502. X
  503. Xsub uucp_request {
  504. X
  505. X    local ($rcpt, $uupath, $uunote, $request, $file, $limit, $parts) = @_;
  506. X
  507. X    if ( $opt_debug ) {
  508. X    print STDERR ("&uucp_request(rcpt=$rcpt, uupath=$uupath,\n",
  509. X              "    uunote=$uunote, request=$request,\n",
  510. X              "    file=$file,\n",
  511. X              "    limit=$limit, parts=$parts)\n");
  512. X    }
  513. X
  514. X    # This routine handles the requests.
  515. X
  516. X    &check_file ($file, 0);
  517. X
  518. X    local ($fname);        # Basename of file to send
  519. X    local ($size);        # Size of file
  520. X    local ($files);        # Number of files to send
  521. X    local (@parts);        # List of parts to send
  522. X    local ($tmpfile_prefix) = $opt_keep || "$tmpdir/drq$$.";
  523. X
  524. X    # Limit must be between 10 and 1024K, with 256K default.
  525. X    $limit =   32*1024 unless defined $limit;
  526. X    $limit = $` * 1024 if $limit =~ /K$/;
  527. X    $limit =   10*1024 if $limit <   10*1024;
  528. X    $limit = 1024*1024 if $limit > 1024*1024;
  529. X
  530. X    # Get last part (basename) of the requested file.
  531. X    $fname = (&fnsplit ($request))[1];
  532. X
  533. X    $size = (stat ($file))[7];
  534. X    if ( $size > $limit ) {
  535. X
  536. X    open (F, $file) || &die ("Cannot read $file [$!]");
  537. X
  538. X    $files = int (($size - 1 ) / $limit) + 1;
  539. X    print STDERR ("Size = $size, files = $files\n")
  540. X        if $opt_debug;
  541. X
  542. X    if (  $parts =~ /\S/ ) {
  543. X        @parts = grep ($_ && $_ <= $files, split (/,/, $parts));
  544. X    }
  545. X    else {
  546. X        @parts = (1..$files);
  547. X    }
  548. X    
  549. X    foreach $the_part ( @parts ) {
  550. X
  551. X        local ($cnt) = 0;
  552. X        local ($need) = $limit;
  553. X        local ($uutmp) = $tmpfile_prefix . "uu";
  554. X
  555. X        print STDERR ("Sending $file, part $the_part of $files\n")
  556. X        if $opt_debug;
  557. X
  558. X        seek (F, ($the_part-1) * $limit, 0);
  559. X        open (S, ">$uutmp") || &die ("Cannot create $uutmp [$!]");
  560. X        while ( $need > 0 ) {
  561. X        local ($try) = 10240;
  562. X        $try = $need if $try > $need;
  563. X        $res = sysread (F, $buf, $try);
  564. X        last unless defined $res && $res > 0;
  565. X        syswrite (S, $buf, $res);
  566. X        $need -= $res;
  567. X        $cnt += $res;
  568. X        }
  569. X        close (S);
  570. X
  571. X        # Send it (w/ copy to UUCP spool).
  572. X        &system ("$uucp -d -r -C -n$uunote $uutmp ".
  573. X             "$uupath/$fname/part" .
  574. X             sprintf ("%02dof%02d", $the_part, $files));
  575. X
  576. X        # Write a log message.
  577. X        $uupath =~ /!/;
  578. X        &writelog ("U \"$`!$uunote\" $request $the_part/$files $cnt");
  579. X
  580. X        unlink ($uutmp) unless $opt_keep;
  581. X    }
  582. X    close (F);
  583. X    }
  584. X    else {
  585. X    print STDERR ("Sending file: ", $file, "\n")
  586. X        if $opt_debug;
  587. X
  588. X    # Send it. Prevent copy to spool.
  589. X    &system ("$uucp -d -r -c -n$uunote $file $uupath/$fname");
  590. X
  591. X    # Write a log message.
  592. X    $uupath =~ /!/;
  593. X    &writelog ("U \"$`!$uunote\" $request 1/1 $size");
  594. X    }
  595. X}
  596. X
  597. X1;
  598. END_OF_FILE
  599.   if test 2794 -ne `wc -c <'dr_uucp.pl'`; then
  600.     echo shar: \"'dr_uucp.pl'\" unpacked with wrong size!
  601.   fi
  602.   # end of 'dr_uucp.pl'
  603. fi
  604. if test -f 'makeindex.pl' -a "${1}" != "-c" ; then 
  605.   echo shar: Will not clobber existing file \"'makeindex.pl'\"
  606. else
  607.   echo shar: Extracting \"'makeindex.pl'\" \(3201 characters\)
  608.   sed "s/^X//" >'makeindex.pl' <<'END_OF_FILE'
  609. X#!/usr/local/bin/perl
  610. X# makeindex.pl -- make index for mail server
  611. X# SCCS Status     : @(#)@ makeindex    1.7
  612. X# Author          : Johan Vromans
  613. X# Created On      : Tue Apr 21 20:36:56 1992
  614. X# Last Modified By: Johan Vromans
  615. X# Last Modified On: Wed May 20 13:37:13 1992
  616. X# Update Count    : 23
  617. X# Status          : Going steady
  618. X
  619. X# makeindex.pl, based on GNU find's updatedb.
  620. X$my_name = "makeindex";
  621. X$my_version = "1.7";
  622. X#
  623. X################ Common stuff ################
  624. X
  625. X$libdir = $ENV{"MSERVLIB"} || "/usr/local/lib/mserv";
  626. Xunshift (@INC, $libdir);
  627. Xrequire "mserv_common.pl";
  628. X
  629. X################ Options handling ################
  630. X
  631. X&options if @ARGV > 0 && $ARGV[0] =~ /^-+[^-]+/;
  632. X@ARGV = ("-") unless @ARGV > 0;
  633. Xprint STDERR "$my_package [$my_name $my_version]\n"
  634. X    if defined $opt_ident;
  635. X
  636. X################ Setup ################
  637. X
  638. X&die ("Index search not selected -- nothing to do")
  639. X    unless $doindexsearch;
  640. X
  641. X# Work files.
  642. X$bigrams  = "$tmpdir/f.bigrams$$";
  643. X$filelist = "$tmpdir/f.list$$";
  644. X$errs     = "$tmpdir/f.errs$$";
  645. X
  646. X$SIG{"INT"}  = "catch";
  647. X$SIG{"QUIT"} = "catch";
  648. X$SIG{"HUP"}  = "IGNORE";
  649. X$SIG{"TERM"} = "catch";
  650. X
  651. X################ Go! ################
  652. X
  653. Xif ( $indexfile =~ m|^/| ) {
  654. X    # Create one single index file.
  655. X    &makeindex (defined $indexlib ? $indexlib : "@libdirs", $indexfile);
  656. X}
  657. Xelse {
  658. X    # Create one index file per library dir.
  659. X    foreach $lib ( @libdirs ) {
  660. X    &makeindex ($lib, "$lib/$indexfile");
  661. X    }
  662. X}
  663. X
  664. Xexit (0);
  665. X
  666. X################ Subroutines ################
  667. X
  668. Xsub makeindex {
  669. X    local ($list, $index) = @_;
  670. X
  671. X    # Make a file list.  Alphabetize '/' before any other char with 'tr'.
  672. X    &system ("$gfind $list ! -type d -follow -printf \"%P\\t%k\\t%Ty%Tm%Td\\n\"" .
  673. X         "| tr '/' '\\001' | sort -f 2> $errs " .
  674. X         "| tr '\\001' '/' > $filelist");
  675. X
  676. X    # Compute common bigrams.
  677. X    &system ("$locatelib/bigram < $filelist | sort 2>> $errs | uniq -c " .
  678. X         "| sort -nr | awk '{ if (NR <= 128) print \$2 }' " .
  679. X         "| tr -d '\\012' > $bigrams");
  680. X
  681. X    printf STDERR ($my_name, ": Out of sort space\n")
  682. X    if -s $errs;
  683. X
  684. X    # Code the file list.
  685. X    &system ("$locatelib/code $bigrams < $filelist > $index~");
  686. X    &rename ("$index~", $index);
  687. X    chmod (0644, $index);
  688. X
  689. X    &cleanup;
  690. X}
  691. X
  692. Xsub system {
  693. X    local ($cmd) = (@_);
  694. X    local ($ret);
  695. X    print STDERR ("+ $cmd\n");
  696. X    $ret = system ($cmd);
  697. X    &die (sprintf ("Return 0x%x from \"$cmd\"", $ret))
  698. X    unless $ret == 0;
  699. X    $ret;
  700. X}
  701. X
  702. Xsub rename {
  703. X    local ($old, $new) = @_;
  704. X    print STDERR ("+ rename $old $new\n");
  705. X    rename ($old, $new) || &system ("mv $old $new");
  706. X}
  707. X
  708. Xsub die {
  709. X    local ($msg) = (@_);
  710. X    warn ($my_name . ": " . $msg . "\n");
  711. X    &cleanup;
  712. X    exit (1);
  713. X}
  714. X
  715. Xsub catch {
  716. X    print STDERR ("+ Ouch!\n");
  717. X    &cleanup;
  718. X    exit(1);
  719. X}
  720. X
  721. Xsub cleanup {
  722. X    unlink ($bigrams, $filelist, $errs);
  723. X}
  724. X
  725. Xsub options {
  726. X    require "newgetopt.pl";
  727. X    if ( !&NGetOpt ("debug", "ident", "trace", "help")
  728. X    || defined $opt_help ) {
  729. X    &usage;
  730. X    }
  731. X}
  732. X
  733. Xsub usage {
  734. X    print STDERR <<EndOfUsage;
  735. X$my_package [$my_name $my_version]
  736. X
  737. XUsage: $my_name [options]
  738. X
  739. XOptions:
  740. X    -help    this message
  741. X    -trace    show commands
  742. X    -ident    show identification
  743. X    -debug    for debugging
  744. XEndOfUsage
  745. X    exit (!defined $opt_help);
  746. X}
  747. END_OF_FILE
  748.   if test 3201 -ne `wc -c <'makeindex.pl'`; then
  749.     echo shar: \"'makeindex.pl'\" unpacked with wrong size!
  750.   fi
  751.   # end of 'makeindex.pl'
  752. fi
  753. if test -f 'ms_lock.pl' -a "${1}" != "-c" ; then 
  754.   echo shar: Will not clobber existing file \"'ms_lock.pl'\"
  755. else
  756.   echo shar: Extracting \"'ms_lock.pl'\" \(2911 characters\)
  757.   sed "s/^X//" >'ms_lock.pl' <<'END_OF_FILE'
  758. X# ms_lock.pl -- locking
  759. X# SCCS Status     : @(#)@ ms_lock.pl    3.1
  760. X# Author          : Johan Vromans
  761. X# Created On      : Thu Jun  4 21:22:45 1992
  762. X# Last Modified By: Johan Vromans
  763. X# Last Modified On: Sat Jun  6 21:01:29 1992
  764. X# Update Count    : 67
  765. X# Status          : OK
  766. X
  767. X# This file defines the function 'locking' as follows:
  768. X#
  769. X#    &locking (*FH, $wait)
  770. X#
  771. X#    FH is a handle to an opened file, with r/w access.
  772. X#    $wait indicates if the process is to wait for the lock.
  773. X#
  774. X# Return values:
  775. X#     1  lock succeeded
  776. X#     0  lock not succeeded, $wait == 0
  777. X#    -1  lock failed
  778. X#
  779. X# Preferrably, &locking is implemented using the fcntl(2) system
  780. X# call that is available on most modern systems.
  781. X# As an alternative, code is included to use flock(2) style locking
  782. X# available on BSD systems.
  783. X# Also code is included to use lockf(2), but this has not been tested.
  784. X# Note that this is lockf(2), not lockf(3): the system call, not the
  785. X# library routine.
  786. X#
  787. X# The functioning of this module can be tested using the program
  788. X# testlock.pl.
  789. X
  790. Xif ( defined $lock_fcntl && $lock_fcntl ) {
  791. X    eval <<'EOD';
  792. X    sub locking {            # using fcntl(2)
  793. X        local (*FH, $wait) = @_;
  794. X
  795. X        require "errno.ph";
  796. X        require "fcntl.ph";
  797. X
  798. X        local ($func) = 
  799. X        $wait ? &F_SETLKW    # set lock and wait for it
  800. X            : &F_SETLK;        # don't wait for it
  801. X        local ($lck) = 
  802. X        pack ("sslli",    # see man for flock(2)
  803. X              &F_WRLCK,    # short l_type (F_WRLCK: write lock)
  804. X              0,    # short l_whence (as in lseek(2))
  805. X              0,    # long l_start (start of region)
  806. X              0,    # long l_len (0 -> whole file)
  807. X              0);    # int l_pid (not used)
  808. X        local ($ret) = fcntl (FH, $func, $lck);
  809. X        return 1 if $ret eq "0 but true";
  810. X        # print STDERR ("=> ret = $ret, \$! = $! [", 0+$!, "]\n");
  811. X        return 0 if $! == &EACCES && !$wait;
  812. X        -1;            # failed
  813. X    }
  814. XEOD
  815. X}
  816. Xelsif ( defined $lock_flock && $lock_flock ) {
  817. X    eval <<'EOD';
  818. X    sub locking {            # using flock(2)
  819. X        local (*FH, $wait) = @_;
  820. X
  821. X        require "sys/file.ph";
  822. X        require "errno.ph";
  823. X
  824. X        local ($wp) = &LOCK_EX;
  825. X        $wp |= &LOCK_NB unless $wait;
  826. X        local ($ret) = flock (FH, $wp);
  827. X        return 1 if $ret;
  828. X        # print STDERR ("=> ret = $ret, \$! = $! [", 0+$!, "]\n");
  829. X        return 0 if $! == &EWOULDBLOCK && !$wait;
  830. X        -1;                # failed
  831. X    }
  832. XEOD
  833. X}
  834. Xelsif ( defined $lock_lockf && $lock_lockf) {
  835. X    eval <<'EOD';
  836. X    sub locking {            # using lockf(2) **UNTESTED**
  837. X        local (*FH, $wait) = @_;
  838. X
  839. X        require "errno.ph";
  840. X        require "unistd.ph";
  841. X        require "sys/syscall.ph";
  842. X
  843. X        local ($func) = $wait ? &F_LOCK : &F_TLOCK;
  844. X        local ($here) = tell (FH);
  845. X
  846. X        seek (FH, 0, 0);
  847. X        local ($ret) = syscall (&SYS_lockf, fileno(FH), $func, 0);
  848. X        seek (FH, $here, 0);
  849. X        return 1 if $ret == 0;
  850. X        return 0 if $! == &EACCES && !$wait;
  851. X        -1;                # failed
  852. X    }
  853. XEOD
  854. X}
  855. Xelse {
  856. X    eval <<'EOD';
  857. X    sub locking {            # no locking
  858. X        local (*FH, $wait) = @_;
  859. X        return $wait ? 1 : 0;
  860. X    }
  861. XEOD
  862. X}
  863. X
  864. X1;
  865. END_OF_FILE
  866.   if test 2911 -ne `wc -c <'ms_lock.pl'`; then
  867.     echo shar: \"'ms_lock.pl'\" unpacked with wrong size!
  868.   fi
  869.   # end of 'ms_lock.pl'
  870. fi
  871. if test -f 'mserv_common.pl' -a "${1}" != "-c" ; then 
  872.   echo shar: Will not clobber existing file \"'mserv_common.pl'\"
  873. else
  874.   echo shar: Extracting \"'mserv_common.pl'\" \(1911 characters\)
  875.   sed "s/^X//" >'mserv_common.pl' <<'END_OF_FILE'
  876. X# mserv_common.pl -- common info for mail server
  877. X# SCCS Status     : @(#)@ mserv_common    1.13
  878. X# Author          : Johan Vromans
  879. X# Created On      : Fri Apr 17 11:02:58 1992
  880. X# Last Modified By: Johan Vromans
  881. X# Last Modified On: Wed Jun 10 14:16:28 1992
  882. X# Update Count    : 68
  883. X# Status          : OK
  884. X
  885. X################ Preamble ################
  886. X#
  887. X# Package info. Do not change this.
  888. X$my_package = "Squirrel Mail Server Software V3.00";
  889. X#
  890. Xrequire "mserv_config.pl";
  891. Xrequire "ms_lock.pl";
  892. X#
  893. X# It is not always clear if 'not setting' means 'not defining' or
  894. X# 'leaving it empty'.
  895. X# This guarantees some consistency.
  896. X
  897. X$chunkmail = $sendmail
  898. X    unless defined $chunkmail && $chunkmail ne "";
  899. X$mserv_bcc = ""
  900. X    unless defined $mserv_bcc;
  901. Xundef $sender
  902. X    unless defined $sender && $sender ne "";
  903. Xundef $mailer_delay
  904. X    unless defined $mailer_delay && $mailer_delay > 0;
  905. Xundef $lockfile
  906. X    unless defined $lockfile && $lockfile ne "";
  907. Xundef $lock_lockf
  908. X    unless defined $lock_lockf && $lock_lockf != 0;
  909. Xundef $lock_flock
  910. X    unless defined $lock_flock && $lock_flock != 0;
  911. Xundef $lock_fcntl
  912. X    unless defined $lock_fcntl && $lock_fcntl != 0;
  913. Xundef $sender
  914. X    unless defined $sender && $sender ne "";
  915. Xundef @x_headers
  916. X    unless defined @x_headers && @x_headers ne 0;
  917. Xundef $logfile
  918. X    unless defined $logfile && $logfile ne "";
  919. Xundef $indexfile
  920. X    unless defined $indexfile && $indexfile ne "";
  921. Xundef $indexlib
  922. X    unless defined $indexfile && defined $indexlib && $indexlib ne "";
  923. X$maxindexlines = 0
  924. X    unless defined $maxindexlines && $maxindexlines > 0;
  925. Xundef $uucp
  926. X    unless defined $uucp && $uucp ne "";
  927. X$uuname = ""
  928. X    unless defined $uuname;
  929. Xundef $packing_limit 
  930. X    unless defined $packing_limit && $packing_limit > 0;
  931. Xundef $pdtar
  932. X    unless defined $pdtar && $pdtar ne "";
  933. X$auto_runrequest = 0
  934. X    unless defined $auto_runrequest && $auto_runrequest > 0;
  935. X
  936. X################ 1 ################
  937. X1;
  938. X
  939. END_OF_FILE
  940.   if test 1911 -ne `wc -c <'mserv_common.pl'`; then
  941.     echo shar: \"'mserv_common.pl'\" unpacked with wrong size!
  942.   fi
  943.   # end of 'mserv_common.pl'
  944. fi
  945. if test -f 'pr_doindex.pl' -a "${1}" != "-c" ; then 
  946.   echo shar: Will not clobber existing file \"'pr_doindex.pl'\"
  947. else
  948.   echo shar: Extracting \"'pr_doindex.pl'\" \(1804 characters\)
  949.   sed "s/^X//" >'pr_doindex.pl' <<'END_OF_FILE'
  950. X# pr_doindex.pl -- execute index requests
  951. X# SCCS Status     : @(#)@ pr_doindex.pl    3.2
  952. X# Author          : Johan Vromans
  953. X# Created On      : Thu Jun  4 22:15:51 1992
  954. X# Last Modified By: Johan Vromans
  955. X# Last Modified On: Wed Jun 10 13:10:07 1992
  956. X# Update Count    : 3
  957. X# Status          : OK
  958. X
  959. Xsub index_loop {
  960. X
  961. X    local ($entries) = 0;
  962. X    local ($name, $size, $date);
  963. X    local ($tally);
  964. X    local ($list_type) = "Index";
  965. X    local ($limit);
  966. X
  967. X    print STDOUT ("Index results:\n");
  968. X
  969. X    foreach $query ( @indexq ) {
  970. X
  971. X    $~ = "list_header";
  972. X    write;
  973. X    $~ = "list_format";
  974. X    $: = " /";        # break filenames at logical places
  975. X    $= = 99999;
  976. X    $tally = 0;
  977. X    $limit = $maxindexlines > 0 ? $maxindexlines : 65535;
  978. X
  979. X    if ( $indexfile =~ m|^/| ) {
  980. X        if ( -r "$indexfile" ) {
  981. X        print STDOUT ("Index $query in $indexfile...\n")
  982. X            if $opt_debug;
  983. X        $ENV{"LOCATE_DB"} = $indexfile;
  984. X        open ( IX, "$ixlookup '$query' |");
  985. X        while ( <IX> ) {
  986. X            ($name, $size, $date) = /^(.+)\?(\d+)\?(\d+)$/;
  987. X            $date =~ s|^(..)(..)(..)|1900+$1."/$2/$3"|e;
  988. X            $size .= "K";
  989. X            write;
  990. X            last if ++$tally >= $limit;
  991. X        }
  992. X        close (IX);
  993. X        }
  994. X    }
  995. X    else {
  996. X        foreach $lib ( @libdirs ) {
  997. X        next unless -r "$lib/$indexfile" || $tally > $limit;
  998. X        print STDOUT ("Index $query in $lib/$indexfile...\n")
  999. X            if $opt_debug;
  1000. X        $ENV{"LOCATE_DB"} = "$lib/$indexfile";
  1001. X        open ( IX, "$ixlookup '$query' |");
  1002. X        while ( <IX> ) {
  1003. X            ($name, $size, $date) = /^(.+)\?(\d+)\?(\d+)$/;
  1004. X            $date =~ s|^(..)(..)(..)|1900+$1."/$2/$3"|e;
  1005. X            $size .= "K";
  1006. X            write;
  1007. X            last if ++$tally >= $limit;
  1008. X        }
  1009. X        close (IX);
  1010. X        }
  1011. X    }
  1012. X    if ( $tally == 0 ) {
  1013. X        $name = "***not found***";
  1014. X        write;
  1015. X    }
  1016. X    elsif ( $tally >= $limit ) {
  1017. X        print STDOUT ("*** Too much output, remaining lines flushed ***\n");
  1018. X    }
  1019. X    }
  1020. X    print STDOUT ("\n");
  1021. X}
  1022. X
  1023. X1;
  1024. END_OF_FILE
  1025.   if test 1804 -ne `wc -c <'pr_doindex.pl'`; then
  1026.     echo shar: \"'pr_doindex.pl'\" unpacked with wrong size!
  1027.   fi
  1028.   # end of 'pr_doindex.pl'
  1029. fi
  1030. if test -f 'pr_dowork.pl' -a "${1}" != "-c" ; then 
  1031.   echo shar: Will not clobber existing file \"'pr_dowork.pl'\"
  1032. else
  1033.   echo shar: Extracting \"'pr_dowork.pl'\" \(5301 characters\)
  1034.   sed "s/^X//" >'pr_dowork.pl' <<'END_OF_FILE'
  1035. X# pr_dowork.pl -- execute work loop
  1036. X# SCCS Status     : @(#)@ pr_dowork.pl    3.1
  1037. X# Author          : Johan Vromans
  1038. X# Created On      : Thu Jun  4 22:14:50 1992
  1039. X# Last Modified By: Johan Vromans
  1040. X# Last Modified On: Thu Jun  4 23:06:00 1992
  1041. X# Update Count    : 3
  1042. X# Status          : OK
  1043. X
  1044. Xsub work_loop {
  1045. X    
  1046. X    local ($def_encoding) = $default_encoding;
  1047. X    local ($packing) = "";
  1048. X    local ($limit) = $limits[1];
  1049. X    local ($uupath) = "";
  1050. X    local ($uunote) = "";
  1051. X    local ($entries);
  1052. X    local (@work);
  1053. X    local ($type);
  1054. X    local ($sender) = $sender;
  1055. X    local ($queueq) = ();
  1056. X
  1057. X    return unless defined ($entries = grep (/^S/, @workq)) && $entries > 0;
  1058. X    
  1059. X    if ( $opt_debug || $opt_trace ) {
  1060. X    print STDOUT ("=> Work queue:\n");
  1061. X    local ($tally) = 0;
  1062. X    foreach $i ( @workq ) {
  1063. X        $tally++;
  1064. X        printf STDOUT ("  %3d: %s\n", $tally, join(" ", &zu ($i)));
  1065. X    }
  1066. X    print STDOUT ("\n");
  1067. X    }
  1068. X
  1069. X    $entries = 0;
  1070. X
  1071. X    foreach $work ( @workq ) {
  1072. X
  1073. X    ($type, @work) = &zu ($work);
  1074. X    last unless defined $type;
  1075. X
  1076. X    if ( $type eq "L" ) {
  1077. X        $limit = $work[0];
  1078. X        next;
  1079. X    }
  1080. X
  1081. X    if ( $type eq "E" ) {
  1082. X        $def_encoding = $work[0];
  1083. X        next;
  1084. X    }
  1085. X
  1086. X    if ( $type eq "M" ) {
  1087. X        $destination = $work[0];
  1088. X        next;
  1089. X    }
  1090. X
  1091. X    if ( $type eq "P" ) {
  1092. X        $packing = $work[0];
  1093. X        next;
  1094. X    }
  1095. X
  1096. X    if ( $type eq "U" ) {
  1097. X        ($uupath, $uunote) = @work;
  1098. X        next;
  1099. X    }
  1100. X
  1101. X    if ( $type eq "S" ) {
  1102. X
  1103. X        local (@found);        # return from search
  1104. X        local ($name, $size, $date, $lib, $subdir); # elements of @found
  1105. X        local ($request, $plist) = @work;
  1106. X        local ($remarks) = "";
  1107. X        local ($limit) = $limit . "K";
  1108. X        local ($coding) = $def_encoding;
  1109. X
  1110. X        if ( $packing ) {
  1111. X        @found = ();
  1112. X        foreach $lib ( @libdirs ) {
  1113. X            print STDOUT ("Trying dir $lib/$request...\n")
  1114. X            if $opt_debug;
  1115. X            push (@found, $lib)
  1116. X            if -d "$lib/$request" && -r _;
  1117. X        }
  1118. X        if ( @found == 1 ) {
  1119. X            local ($lib) = $found[0];
  1120. X            print STDOUT ("Sizing dir $lib/$request... ")
  1121. X            if $opt_debug;
  1122. X            $size = `$du -s $lib/$request` + 0;
  1123. X            print STDOUT ($size, " blocks.\n")
  1124. X            if $opt_debug;
  1125. X            if ($size > $packing_limit) {
  1126. X            push (@queueq, 
  1127. X                  &zp ($request . "/ (" . $packing . ")",
  1128. X                   "", "", "", "Request too big"));
  1129. X            }
  1130. X            else {
  1131. X
  1132. X            # Put the request in the batch queue.
  1133. X            if ( $opt_noqueue ) {
  1134. X                $remarks = "Tested OK";
  1135. X                $entries++;
  1136. X            }
  1137. X            elsif ( $method eq "M" ) {
  1138. X                $remarks =
  1139. X                &enqueue ("MP", $recipient, $destination, 
  1140. X                      $request, "$lib/$request",
  1141. X                      $coding, $limit, $packing,
  1142. X                      $plist);
  1143. X            }
  1144. X            elsif ( $method eq "U" ) {
  1145. X                $remarks =
  1146. X                &enqueue ("UP", $recipient, $uupath, $uunote, 
  1147. X                      $request, "$lib/$request",
  1148. X                      $limit, $packing, $plist);
  1149. X            }
  1150. X            push (@queueq,
  1151. X                  &zp ($request . "/ (" . $packing . ")",
  1152. X                   int(($size+1) / 2) . "K",
  1153. X                   $coding, $limit, $remarks));
  1154. X            }
  1155. X        }
  1156. X        elsif ( @found == 0 ) {
  1157. X            push (@queueq, 
  1158. X              &zp ($request . "/ (" . $packing . ")",
  1159. X                   "", "", "", "Not found"));
  1160. X        }
  1161. X        else {
  1162. X            # Ambiguous.
  1163. X            print STDOUT ("Directory \"$request\" is not unique in the archives.\n",
  1164. X                  "This request has been skipped.\n\n");
  1165. X            push (@queueq, 
  1166. X              &zp ($request . "/ (" . $packing . ")",
  1167. X                   "", "", "", "Ambiguous"));
  1168. X        }
  1169. X        next;
  1170. X        }
  1171. X
  1172. X        # Locate them.
  1173. X        @found = &search ($request, 0);
  1174. X
  1175. X        if ( @found > 1 ) {
  1176. X        print STDOUT ("Request \"$request\" is ambiguous:\n");
  1177. X        &dolist ("Search", $request, *found);
  1178. X        print STDOUT ("\n");
  1179. X        push (@queueq, 
  1180. X              &zp ($request, "", "", "", "Ambiguous"));
  1181. X        next;
  1182. X        }
  1183. X
  1184. X        ($name, $size, $date, $lib, $subdir) = &zu ($found[0]);
  1185. X
  1186. X        # Make sure that we have one single file.
  1187. X        if ( @found == 0 || ! -f $lib.$subdir.$name ) {
  1188. X        push (@queueq,
  1189. X              &zp ($request, "", "", "", "Not found"));
  1190. X        next;
  1191. X        }
  1192. X
  1193. X        # Send some files in plain (ascii) format.
  1194. X        $coding = "A" if ($name !~ /$extpat$/ || $+ eq ".shar")
  1195. X        && -T $lib.$subdir.$name ;
  1196. X
  1197. X        $size = int(($size+1023)/1024) . "K" unless $size =~ /K$/;
  1198. X
  1199. X        # Put the request in the batch queue.
  1200. X        if ( $opt_noqueue ) {
  1201. X        $remarks = "Tested OK";
  1202. X        $entries++;
  1203. X        }
  1204. X        elsif ( $method eq "M" ) {
  1205. X        $remarks =
  1206. X            &enqueue ("M", $recipient, $destination, $subdir.$name,
  1207. X                  $lib.$subdir.$name,
  1208. X                  $coding, $limit, $plist);
  1209. X        }
  1210. X        elsif ( $method eq "U" ) {
  1211. X        $remarks =
  1212. X            &enqueue ("U", $recipient, $uupath, $uunote, $subdir.$name,
  1213. X                  $lib.$subdir.$name,
  1214. X                  $limit, $plist);
  1215. X        }
  1216. X
  1217. X        push (@queueq,
  1218. X          &zp ($subdir.$name, $size, $coding, $limit, $remarks));
  1219. X        next;
  1220. X    }
  1221. X
  1222. X    # Should not happen.
  1223. X    print STDOUT ("*** Mail Server internal error: ",
  1224. X              "Request type \"$type\" in work queue ***\n");
  1225. X    }
  1226. X
  1227. X    if ( @queueq > 0 ) {
  1228. X    print STDOUT ("Request results:\n");
  1229. X    $~ = $method . "_header";
  1230. X    write;
  1231. X    $~ = $method . "_list";
  1232. X    $: = " /";
  1233. X    $= = 99999;
  1234. X
  1235. X    foreach $entry ( @queueq ) {
  1236. X        local ($name, $size, $coding, $limit, $remarks) = &zu ($entry);
  1237. X        write;
  1238. X    }
  1239. X
  1240. X    if ( $entries > 0 ) {
  1241. X        print STDOUT ("\nThe requests with status \"Queued\"",
  1242. X              " will be sent as soon as the load of\n",
  1243. X              "the server system permits, ",
  1244. X              "usually within 24 hours.\n");
  1245. X    }
  1246. X    else {
  1247. X        print STDOUT ("\nNo requests remain to be send.\n");
  1248. X    }
  1249. X    }
  1250. X    else {
  1251. X    print STDOUT ("\nNo requests remain to be send.\n");
  1252. X    }
  1253. X}
  1254. X
  1255. X1;
  1256. END_OF_FILE
  1257.   if test 5301 -ne `wc -c <'pr_dowork.pl'`; then
  1258.     echo shar: \"'pr_dowork.pl'\" unpacked with wrong size!
  1259.   fi
  1260.   # end of 'pr_dowork.pl'
  1261. fi
  1262. if test -f 'pr_dsearch.pl' -a "${1}" != "-c" ; then 
  1263.   echo shar: Will not clobber existing file \"'pr_dsearch.pl'\"
  1264. else
  1265.   echo shar: Extracting \"'pr_dsearch.pl'\" \(2649 characters\)
  1266.   sed "s/^X//" >'pr_dsearch.pl' <<'END_OF_FILE'
  1267. X# pr_dsearch.pl -- directory search
  1268. X# SCCS Status     : @(#)@ pr_dsearch.pl    3.1
  1269. X# Author          : Johan Vromans
  1270. X# Created On      : Thu Jun  4 22:13:23 1992
  1271. X# Last Modified By: Johan Vromans
  1272. X# Last Modified On: Thu Jun  4 23:05:39 1992
  1273. X# Update Count    : 4
  1274. X# Status          : OK
  1275. X
  1276. Xsub dirsearch {
  1277. X
  1278. X    local ($libdir, $request) = @_;
  1279. X
  1280. X    # Locate an archive item $request in library $libdir by
  1281. X    # performing a directory lookup.
  1282. X    # Eligible items are in the format XXX.EXT, or XXX-VVV.EXT, where
  1283. X    # VVV is assumed to be a version indicator (and must start with a digit).
  1284. X    # If an eligible item appears to be a directory, the search continues
  1285. X    # recursively.
  1286. X    #
  1287. X    # See "sub search" for a description of the return values.
  1288. X
  1289. X    local ($size);
  1290. X    local (@retval);        # return value
  1291. X    local (@a);            # to hold stat() result
  1292. X
  1293. X    # Normalize the request. 
  1294. X    # $tryfile will be the basename of the request.
  1295. X    # $subdir holds the part between $libdir and $tryfile.
  1296. X    local ($subdir, $tryfile) = &fnsplit ($request);
  1297. X
  1298. X    print STDOUT ("Search $libdir$subdir for $tryfile...\n") if $opt_debug;
  1299. X
  1300. X    $subdir .= "/" if $subdir && $subdir !~ m|/$|;
  1301. X    $libdir .= "/" if $libdir && $libdir !~ m|/$|;
  1302. X
  1303. X    # Gather files info for the lib dir.
  1304. X    local (@files, @found, $pat);
  1305. X
  1306. X    # Get all filenames.
  1307. X    opendir (DIR, $libdir.$subdir);
  1308. X    @files = readdir (DIR);
  1309. X    closedir (DIR);
  1310. X    local ($tmp) = 0+@files if $opt_debug;
  1311. X    return @retval unless @files > 0;    # No need to proceed.
  1312. X
  1313. X    # Form pattern to match search arg.
  1314. X    ($pat = $tryfile) =~ s/(\W)/\\\1/g;
  1315. X
  1316. X    # Extract valid items.
  1317. X    @found = grep(/^$pat/, @files);
  1318. X    print STDOUT ("Found ", 0+@found, " candidates out of ", $tmp, " files.\n")
  1319. X    if $opt_debug;
  1320. X    @files = ();        # Deallocate.
  1321. X
  1322. X    return @retval unless @found > 0;    # No need to proceed.
  1323. X
  1324. X    foreach $file ( @found ) {
  1325. X
  1326. X    local ($base, $version, $extension);
  1327. X
  1328. X    (($base, $version, $extension) =
  1329. X     $file =~ /^($pat)(-\d.*|)$extpat$/)
  1330. X        || (($base, $version, $extension) =
  1331. X        $file =~ /^($pat)(-\d.*|)$/);
  1332. X
  1333. X    # Nope.
  1334. X    next unless defined $base;
  1335. X
  1336. X    $extension = "" unless defined $extension;
  1337. X
  1338. X    # Recurse if directory.
  1339. X    if ( -d $libdir.$subdir.$file && -r _ ) {
  1340. X        print STDOUT ("File $libdir$subdir$file (directory)\n")
  1341. X        if $opt_debug;
  1342. X        push (@retval, 
  1343. X          &dirsearch ($libdir, "$subdir$file/$tryfile"));
  1344. X        next;
  1345. X    }
  1346. X
  1347. X    # Try file.
  1348. X    next unless -f _ && -r _ ;
  1349. X
  1350. X    # We have a file.
  1351. X    @a = stat(_);
  1352. X    print STDOUT ("File $libdir$subdir$file (known)\n")
  1353. X        if $opt_debug;
  1354. X    push (@retval, 
  1355. X          &zp ($base.$version.$extension, $a[7], $a[9], $libdir, $subdir));
  1356. X    }
  1357. X
  1358. X    return @retval;
  1359. X}
  1360. X
  1361. X1;
  1362. END_OF_FILE
  1363.   if test 2649 -ne `wc -c <'pr_dsearch.pl'`; then
  1364.     echo shar: \"'pr_dsearch.pl'\" unpacked with wrong size!
  1365.   fi
  1366.   # end of 'pr_dsearch.pl'
  1367. fi
  1368. if test -f 'pr_isearch.pl' -a "${1}" != "-c" ; then 
  1369.   echo shar: Will not clobber existing file \"'pr_isearch.pl'\"
  1370. else
  1371.   echo shar: Extracting \"'pr_isearch.pl'\" \(2320 characters\)
  1372.   sed "s/^X//" >'pr_isearch.pl' <<'END_OF_FILE'
  1373. X# pr_isearch.pl -- index search
  1374. X# SCCS Status     : @(#)@ pr_isearch.pl    3.2
  1375. X# Author          : Johan Vromans
  1376. X# Created On      : Thu Jun  4 22:13:56 1992
  1377. X# Last Modified By: Johan Vromans
  1378. X# Last Modified On: Wed Jun 10 12:00:11 1992
  1379. X# Update Count    : 6
  1380. X# Status          : OK
  1381. X
  1382. Xsub indexsearch {
  1383. X
  1384. X    local ($ixfile, $lib, $request) = @_;
  1385. X
  1386. X    # Locate an archive item $request in library $libdir by
  1387. X    # inspecting the associated index file.
  1388. X    # Eligible items are in the format XXX.EXT, or XXX-VVV.EXT, where
  1389. X    # VVV is assumed to be a version indicator (and must start with a digit).
  1390. X    #
  1391. X    # See "sub search" for a description of the return values.
  1392. X
  1393. X    return () unless -s $ixfile;
  1394. X
  1395. X    # Lookup a request in index.
  1396. X
  1397. X    local ($tryfile, $subdir, $pat);
  1398. X    local (@retval);        # return value
  1399. X
  1400. X    # Normalize the request.
  1401. X    ($subdir, $tryfile) = &fnsplit ($request);
  1402. X    $pat = $subdir ne "" ? "$subdir/$tryfile" : $tryfile;
  1403. X    $pat =~ s/(\W)/\\\1/g;
  1404. X
  1405. X    print STDOUT ("Lookup $tryfile ($pat) in $ixfile...\n") if $opt_debug;
  1406. X
  1407. X    # GNU locate 3.6 (or a customized version of GNU locate 3.5)
  1408. X    # will return info.
  1409. X    $ENV{"LOCATE_DB"} = $ixfile;
  1410. X    open (INDEX, "$ixlookup '$tryfile' |");
  1411. X
  1412. X    local ($base, $version, $extension);
  1413. X    local ($date, $size, $file);
  1414. X
  1415. X    while ( <INDEX> ) {
  1416. X    chop;
  1417. X
  1418. X    # Returned info: path?size in K?mdate, e.g.
  1419. X    # zoo-2.01/zoo.TZ?172?910807
  1420. X
  1421. X    ($file, $size, $date) = /^(.+)\?(\d+)\?(\d+)$/;
  1422. X
  1423. X    if ( defined $file ) {
  1424. X
  1425. X        (($base, $version, $extension) =
  1426. X         $file =~ m:^($pat|.+/$pat)(-\d[^/]*|)$extpat$:)
  1427. X        || (($base, $version, $extension) =
  1428. X            $file =~ m:^($pat|.+/$pat)(-\d[^/]*|)$:);
  1429. X
  1430. X        # Nope.
  1431. X        next unless defined $base;
  1432. X        $file = $base;
  1433. X
  1434. X        # Adjust XX -YYY.tar .Z -> XX -YYY .tar.Z 
  1435. X        $extension = "" unless defined $extension;
  1436. X        ($version, $extension) = ($`, $&.$extension) 
  1437. X        if $extension eq ".Z" && $version =~ /\.(sh|t)ar$/;
  1438. X
  1439. X        $date =~ s|^(..)(..)(..)|1900+$1."/$2/$3"|e;
  1440. X
  1441. X        ($subdir, $base) = &fnsplit ($file);
  1442. X        $subdir .= "/" if $subdir ne "";
  1443. X        $lib .= "/" unless $lib =~ m|/$|;
  1444. X
  1445. X        push (@retval,
  1446. X          &zp ($base.$version.$extension, $size."K", "T".$date,
  1447. X               $lib, $subdir));
  1448. X        next;
  1449. X    }
  1450. X
  1451. X    }
  1452. X
  1453. X    close (INDEX);
  1454. X    print STDOUT ("Found ", 0+@retval, " entries\n") if $opt_debug;
  1455. X    @retval;
  1456. X}
  1457. X
  1458. X1;
  1459. END_OF_FILE
  1460.   if test 2320 -ne `wc -c <'pr_isearch.pl'`; then
  1461.     echo shar: \"'pr_isearch.pl'\" unpacked with wrong size!
  1462.   fi
  1463.   # end of 'pr_isearch.pl'
  1464. fi
  1465. if test -f 'report.pl' -a "${1}" != "-c" ; then 
  1466.   echo shar: Will not clobber existing file \"'report.pl'\"
  1467. else
  1468.   echo shar: Extracting \"'report.pl'\" \(6484 characters\)
  1469.   sed "s/^X//" >'report.pl' <<'END_OF_FILE'
  1470. X#!/usr/local/bin/perl
  1471. X# report.pl -- make mail server report
  1472. X# SCCS Status     : @(#)@ report    3.6
  1473. X# Author          : Johan Vromans
  1474. X# Created On      : Sat May  2 14:23:10 1992
  1475. X# Last Modified By: Johan Vromans
  1476. X# Last Modified On: Tue May 12 23:09:50 1992
  1477. X# Update Count    : 45
  1478. X# Status          : Unknown, Use with caution!
  1479. X
  1480. X# Read the mail server logfile, and create a report.
  1481. X
  1482. X$my_name = "report";
  1483. X$my_version = "3.6";
  1484. X#
  1485. X################ Common stuff ################
  1486. X
  1487. X$libdir = $ENV{"MSERVLIB"} || "/usr/local/lib/mserv";
  1488. Xunshift (@INC, $libdir);
  1489. Xrequire "mserv_common.pl";
  1490. X
  1491. X################ Options handling ################
  1492. X
  1493. X&options if @ARGV > 0 && $ARGV[0] =~ /^-+[^-]+/;
  1494. X$opt_usage = 1 unless $opt_errors;
  1495. X@ARGV = ( $logfile ) unless @ARGV > 0;
  1496. X$now = time;
  1497. X
  1498. X################ Preamble ################
  1499. X
  1500. Xrequire "$libdir/rfc822.pl";
  1501. X
  1502. Xformat std_hdr =
  1503. XMail Server Report for @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<     @>>>>>>>>>>>>
  1504. X"$thismonth 19$year -- by $report_type", "Page $%"
  1505. X
  1506. X                                                         1111111111222222222233
  1507. X@<<<<<<<<<<<<<<<<<<<                 Type Total 1234567890123456789012345678901
  1508. X$report_type
  1509. X-------------------------------------------------------------------------------
  1510. X.
  1511. X
  1512. Xformat std_out =
  1513. X^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @ @>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1514. X$item, $type, $count, $seq
  1515. X ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
  1516. X$item
  1517. X.
  1518. X
  1519. X################ Main ################
  1520. X
  1521. X$logfile = $ARGV[0] if @ARGV == 1;
  1522. X
  1523. Xopen (LOG, $logfile) || die ("$my_name: Cannot open $logfile [$!]\n");
  1524. X
  1525. X$curmonth = "";
  1526. X@mnames = split (/,/, "January,February,March,April,May,June," .
  1527. X        "July,August,September,October,November,December");
  1528. X
  1529. X# Form pattern for the known libraries so we can easily
  1530. X# strip them off the names of the requests.
  1531. X$libpat = "(";
  1532. Xforeach $lib ( @libdirs ) {
  1533. X    $lib =~ s/(\W)/\\\1/g;
  1534. X    $libpat .= $lib . "|";
  1535. X}
  1536. Xchop ($libpat);
  1537. X$libpat .= ")";
  1538. X
  1539. X# Process logfile.
  1540. X$msgcnt = 0;
  1541. Xwhile ( <LOG> ) {
  1542. X
  1543. X    # 891002 19:48 M "Neil Dixon <neil@yc1>" /u2/goodies/gwm/INDEX U1/1 32678
  1544. X    #    0     1   2             3                  4                5    6
  1545. X
  1546. X    # Note: $size is not used (yet).
  1547. X    ($date, $time, $type, $user, $pkg, $part, $size) = 
  1548. X    /^(\S+)\s+(\S+)\s(\S)\s+"([^\042]+)"\s+(\S+)\s+(\S+)\s+(\S+)$/;
  1549. X
  1550. X    unless ( defined $user ) {    # Assume error record.
  1551. X
  1552. X    next unless $opt_errors;
  1553. X
  1554. X    ($date, $time, $msg) = 
  1555. X        /^(\S+)\s+(\S+)\s+(.+)$/;
  1556. X    $date .= " " . $time;
  1557. X    next if $since && $date lt $since; 
  1558. X
  1559. X    if ( $msgcnt == 0 && $since ) {
  1560. X        print STDERR ("Errors since $since\n\n");
  1561. X    }
  1562. X    print STDERR ($date, " ", $msg, "\n");
  1563. X    $msgcnt++;
  1564. X    next;
  1565. X    }
  1566. X
  1567. X    next unless $opt_usage;
  1568. X
  1569. X    # Use first parts for accounting only.
  1570. X    next unless $part =~ m|^\w*1/|;
  1571. X
  1572. X    # Get date.
  1573. X    $year = substr ($date, 0, 2);
  1574. X    $month = substr ($date, 2, 2);
  1575. X    $day = substr ($date, 4, 2);
  1576. X
  1577. X    # Strip known libraries.
  1578. X    $pkg = $' if $pkg =~ /$libpat\//o;
  1579. X    $pkg .= $type;
  1580. X
  1581. X    # Generate a new report page if the month runs over.
  1582. X    if ( $curmonth ne $month ) {
  1583. X    if ( $curmonth ne "" ) {
  1584. X        &report;
  1585. X        $- = 0;            # Force page break.
  1586. X        reset "Z";
  1587. X    }
  1588. X    $curmonth = $month;
  1589. X    $thismonth = $mnames[$curmonth-1];
  1590. X    $weeksh = &firstday ($month, $year);
  1591. X    }
  1592. X
  1593. X    # Normalize addresses and count them.
  1594. X    &rfc822'parse_addresses ($user);
  1595. X    $user = $rfc822'addresses[0] . $type;
  1596. X    $Zucounts{$user}++;
  1597. X    $Zudays{$user} |= 1 << ($day - 1);
  1598. X    $Zpcounts{$pkg}++;
  1599. X    $Zpdays{$pkg} |= 1 << ($day - 1);
  1600. X}
  1601. Xclose (LOG);
  1602. X
  1603. X# Update since-file.
  1604. Xif ( $opt_since && !$opt_noupdate ) {
  1605. X    utime ($now, $now, $opt_since) ||
  1606. X    print STDERR ("Cannot change times on \"$opt_since\" [$!]\n");
  1607. X}
  1608. X
  1609. X# Now for the remaining usage reports ...
  1610. X&report if $opt_usage;
  1611. X
  1612. X# That's it ...
  1613. Xexit (0);
  1614. X
  1615. X################ Subroutines ################
  1616. X
  1617. Xsub report {
  1618. X    $^ = "std_hdr";
  1619. X    $~ = "std_out";
  1620. X    $: = " \n-/";
  1621. X    &report1;
  1622. X    &report2;
  1623. X}
  1624. X
  1625. Xsub report1 {
  1626. X    $report_type = "User";
  1627. X    $- = 0;
  1628. X    $% = 0;
  1629. X    foreach $item (sort (keys (%Zucounts))) {
  1630. X    $seq = &daylist ($Zudays{$item});
  1631. X    $count = $Zucounts{$item};
  1632. X    $type = chop ($item);
  1633. X    write;
  1634. X    }
  1635. X}
  1636. X
  1637. Xsub report2 {
  1638. X    $report_type = "Package";
  1639. X    $- = 0;
  1640. X    $% = 0;
  1641. X    foreach $item (sort (keys (%Zpcounts))) {
  1642. X    $seq = &daylist ($Zpdays{$item});
  1643. X    $count = $Zpcounts{$item};
  1644. X    $type = chop ($item);
  1645. X    write;
  1646. X    }
  1647. X}
  1648. X
  1649. Xsub daylist {
  1650. X    local ($day) = pop (@_);
  1651. X    local ($seq) = "";
  1652. X    local ($cc) = 1;
  1653. X
  1654. X    while ( $cc <= 31 ) {
  1655. X    if ( $day & 0x1 ) {
  1656. X        $seq .= substr ("SMTWTFS", ($cc - $weeksh + 7) % 7, 1);
  1657. X    }
  1658. X    else {
  1659. X        $seq = "$seq ";
  1660. X    }
  1661. X    $day >>= 1;
  1662. X    $cc++;
  1663. X    }
  1664. X    return $seq;
  1665. X}
  1666. X
  1667. Xsub firstday {
  1668. X    local ($month) = shift (@_);
  1669. X    local ($year) = shift (@_);
  1670. X    local ($t);
  1671. X    local (@tm); 
  1672. X
  1673. X    $t = 
  1674. X    ($year - 70) * (365 * 24 * 60 * 60) +
  1675. X        ($month - 1) * (28 * 24 * 60 * 60);
  1676. X    $month--;
  1677. X
  1678. X    do {
  1679. X    @tm = localtime ($t);
  1680. X    $t += (28 * 24 * 60 * 60);
  1681. X    }
  1682. X    while (($tm[5] < $year) || ($tm[4] < $month));
  1683. X
  1684. X    $t = ($tm[3] - $tm[6]) % 7;
  1685. X    $t += 7 if $t < 0;
  1686. X    return $t;
  1687. X}
  1688. X
  1689. Xsub options {
  1690. X    local ($opt_full, $opt_help, $opt_ident) = (0, 0, 0);
  1691. X
  1692. X    require "newgetopt.pl";
  1693. X
  1694. X    $opt_errors = $opt_usage = 0;
  1695. X    if ( !&NGetOpt ("ident", "errors", "usage", "full",
  1696. X            "since=s", "noupdate",
  1697. X            "help")
  1698. X    || $opt_help
  1699. X    || (@ARGV > 1)) {
  1700. X    &usage;
  1701. X    }
  1702. X    $opt_errors |= $opt_full;
  1703. X    $opt_usage |= $opt_full;
  1704. X    print ($my_package, " [", $my_name, " ", $my_version, "]\n")
  1705. X    if $opt_ident && $opt_usage;
  1706. X    print STDERR ($my_package, " [", $my_name, " ", $my_version, "]\n")
  1707. X    if $opt_ident && $opt_errors;
  1708. X    if ( defined $opt_since ) {
  1709. X    local ($a) = (stat ($opt_since))[9];
  1710. X    die ("Cannot timestamp \"$opt_since\" [$!]\n") unless $a > 0;
  1711. X    local (@tm) = localtime ($a);
  1712. X    $since = sprintf ("%02d%02d%02d %02d:%02d",
  1713. X              $tm[5], 1+$tm[4], $tm[3], $tm[2], $tm[1]);
  1714. X    $opt_noupdate = defined $opt_noupdate;
  1715. X    }
  1716. X    else {
  1717. X    $since = "";
  1718. X    }
  1719. X}
  1720. X
  1721. Xsub usage {
  1722. X    print STDERR <<EndOfUsage;
  1723. X$my_package [$my_name $my_version]
  1724. X
  1725. XUsage: $my_name [options] [ logfile ]
  1726. X
  1727. XOptions:
  1728. X    -errors    generate error report to STDERR
  1729. X    -usage    generate usage report to STDOUT
  1730. X    -full    generate usage report and error report
  1731. X    -since FILE    only error messages newer than FILE
  1732. X        (FILE date will be updated upon successful completion)
  1733. X    -noupdate    do not update FILE
  1734. X    -help    this message
  1735. X    -ident    print program identification
  1736. X
  1737. XDefault action is to generate a usage report from logfile
  1738. X"$logfile".
  1739. XEndOfUsage
  1740. X    exit (1);
  1741. X}
  1742. END_OF_FILE
  1743.   if test 6484 -ne `wc -c <'report.pl'`; then
  1744.     echo shar: \"'report.pl'\" unpacked with wrong size!
  1745.   fi
  1746.   # end of 'report.pl'
  1747. fi
  1748. if test -f 'rfc822.pl' -a "${1}" != "-c" ; then 
  1749.   echo shar: Will not clobber existing file \"'rfc822.pl'\"
  1750. else
  1751.   echo shar: Extracting \"'rfc822.pl'\" \(4456 characters\)
  1752.   sed "s/^X//" >'rfc822.pl' <<'END_OF_FILE'
  1753. X# rfc822.pl -- RFC822 support
  1754. X# SCCS Status     : @(#)@ rfc822    2.2
  1755. X# Author          : Johan Vromans
  1756. X# Created On      : Oct 26 20:39:18 1989
  1757. X# Last Modified By: Johan Vromans
  1758. X# Last Modified On: Thu Apr 30 14:56:44 1992
  1759. X# Update Count    : 29
  1760. X# Status          : OK
  1761. X#
  1762. X# Copyright 1989, 1992 Johan Vromans
  1763. X#
  1764. X# This software may be redistributed on the same terms as the 
  1765. X# GNU Public Licence.
  1766. X
  1767. X# Exported routines
  1768. X#
  1769. X#   start_read -- initializes this module
  1770. X#
  1771. X#    must be passed the filename to read from
  1772. X#
  1773. X#   read_header -- reads, and parses RFC822 header
  1774. X#
  1775. X#    returns $VALID_HEADER if a valid RFC822 header was found.
  1776. X#    $header and $contents contain the header and contents.
  1777. X#    $line contains the normalized header.
  1778. X#
  1779. X#   read_body -- reads a line from the message body
  1780. X#
  1781. X#    returns $EMPTY_LINE if an empty line was read.
  1782. X#
  1783. X#    returns $DATA_LINE otherwise.
  1784. X#    $line contains the contents of the line.
  1785. X#
  1786. X#   parse_addresses -- parses an address specification.
  1787. X#
  1788. X#    return addresses in @addresses, the address
  1789. X#    comments in %addr_comments.
  1790. X#
  1791. X
  1792. X# Export the routines in the requiring package.
  1793. X*start_read = *rfc822'start_read;
  1794. X*read_header = *rfc822'read_header;
  1795. X*read_body = *rfc822'read_body;
  1796. X*parse_addresses = *rfc822'parse_addresses;
  1797. X
  1798. X# Switch to package context.
  1799. Xpackage rfc822;
  1800. X
  1801. X$[ = 0;                # let arrays start at 0 ];
  1802. X
  1803. X################ Global constants ################
  1804. X$EOF = 0;
  1805. X$VALID_HEADER = 1;
  1806. X$EMPTY_LINE = 2;
  1807. X$DATA_LINE = 3;
  1808. X
  1809. X################ Variables ################
  1810. X$version = "@(#)@ rfc822    2.2 - rfc822.pl";
  1811. Xundef $line_in_cache;
  1812. X$have_input_stream = 0;
  1813. X$line = "";
  1814. X$header = "";
  1815. X$contents = "";
  1816. X@addresses = ();
  1817. X%addr_comments = ();
  1818. Xlocal (*INPUT);
  1819. X
  1820. X################ Subroutines ################
  1821. X
  1822. Xsub start_read {
  1823. X    local ($file) = @_;
  1824. X
  1825. X    close (INPUT) if $have_input_stream;
  1826. X
  1827. X    return 0 unless open (INPUT, $file);
  1828. X
  1829. X    # Initialize the read ahead system.
  1830. X    $line_in_cache = <INPUT>;
  1831. X
  1832. X    # Will supply return value.
  1833. X    $have_input_stream = 1;
  1834. X}
  1835. X
  1836. Xsub read_body {
  1837. X
  1838. X    if ( defined $line_in_cache ) {
  1839. X    $line = $line_in_cache;
  1840. X    undef $line_in_cache;
  1841. X    } 
  1842. X    else {
  1843. X    return $EOF if eof(INPUT);
  1844. X    $line = <INPUT>;
  1845. X    }
  1846. X
  1847. X    chop ($line);
  1848. X    $header = $contents = undef;
  1849. X    return ($line eq "") ? $EMPTY_LINE : $DATA_LINE;
  1850. X}
  1851. X
  1852. Xsub read_header {
  1853. X
  1854. X    if ( defined $line_in_cache ) {
  1855. X    $line = $line_in_cache;
  1856. X    undef $line_in_cache;
  1857. X    } 
  1858. X    else {
  1859. X    return $EOF if eof(INPUT);
  1860. X    $line = <INPUT>;
  1861. X    }
  1862. X
  1863. X    chop ($line);
  1864. X    if ( $line =~ /^([-\w]+)\s*:\s*/ ) {
  1865. X    $header = $1;
  1866. X    $contents = $';            #';
  1867. X    } 
  1868. X    else {
  1869. X    $header = $contents = undef;
  1870. X    return ($line eq "") ? $EMPTY_LINE : $DATA_LINE;
  1871. X    }
  1872. X
  1873. X    # Handle continuation lines.
  1874. X    while ( ! eof(INPUT) ) {
  1875. X    chop ($line = <INPUT>);
  1876. X    if ( $line =~ /^\s+/ ) {
  1877. X        # Append.
  1878. X        $contents .= " " . $';        #';
  1879. X    }
  1880. X    else {
  1881. X        # Too far.
  1882. X        $line_in_cache = $line . "\n";
  1883. X        last;
  1884. X    }
  1885. X    }
  1886. X
  1887. X    $line = $header . ": " . $contents;
  1888. X    return $VALID_HEADER;
  1889. X}
  1890. X
  1891. Xsub parse_addresses {
  1892. X
  1893. X    # Given an RFC822 compliant series of addresses, parse them, and
  1894. X    # return:
  1895. X    #    @addresses -- array with parsed addresses.
  1896. X    #    %addr_comments -- the comments for each of the addresses.
  1897. X    #
  1898. X    # RFC822 syntax:
  1899. X    #    address [, address ...]
  1900. X    #    address: addr [ ( comment ) ] | [ comment ] <addr>
  1901. X
  1902. X    local ($addr) = shift (@_);
  1903. X    local ($left);
  1904. X    local (@left);
  1905. X    local ($right);
  1906. X    local ($comment);
  1907. X
  1908. X    @addresses = ();
  1909. X    %addr_comments = ();
  1910. X
  1911. X    # First break out the (...) comments.
  1912. X    while ( $addr =~ /\(([^)]*)\)/ ) {
  1913. X    $right = $';
  1914. X    $comment = $1;
  1915. X    @left = split (/[ \t]+/, $`);
  1916. X    if ( $#left >= 0 ) {
  1917. X        # print "() match: \"", $left[$#left], "\" -> \"$1\"\n";
  1918. X        unshift (@addresses, pop (@left));
  1919. X        $addr_comments{$addresses[0]} = $1;
  1920. X    }
  1921. X    if ( $right =~ /^\s*,\s*/ ) {
  1922. X        $right = $';
  1923. X    }
  1924. X    $addr = join (" ", @left) . " " . $right;
  1925. X    # print "todo: $addr\n";
  1926. X    }
  1927. X
  1928. X    # Then split on commas, and handle each part separately.
  1929. X    @addr = split (/,/, $addr);
  1930. X
  1931. X    while ( $#addr >= 0 ) {
  1932. X    $addr = shift (@addr);
  1933. X    # print "doing: \"$addr\"\n";
  1934. X    $addr = $' if $addr =~ /^\s+/ ;
  1935. X    $addr = $` if $addr =~ /\s+$/ ;
  1936. X    next if $addr eq "";
  1937. X    if ( $addr =~ /<([^>]+)>/ ) {
  1938. X        # print "\"$addr\" matched: \"$`\"-\"$+\"-\"$'\"\n";
  1939. X        unshift (@addresses, $1);
  1940. X        $addr_comments{$1} = join (" ", split (/[ \t]+/, "$` $'"));
  1941. X    }
  1942. X    else {
  1943. X        unshift (@addresses, $addr);
  1944. X        $addr_comments{$addr} = "";
  1945. X        # print "did: \"$addr\"\n";
  1946. X    }
  1947. X    }
  1948. X}
  1949. X
  1950. X1;
  1951. END_OF_FILE
  1952.   if test 4456 -ne `wc -c <'rfc822.pl'`; then
  1953.     echo shar: \"'rfc822.pl'\" unpacked with wrong size!
  1954.   fi
  1955.   # end of 'rfc822.pl'
  1956. fi
  1957. if test -f 'testlock.pl' -a "${1}" != "-c" ; then 
  1958.   echo shar: Will not clobber existing file \"'testlock.pl'\"
  1959. else
  1960.   echo shar: Extracting \"'testlock.pl'\" \(1542 characters\)
  1961.   sed "s/^X//" >'testlock.pl' <<'END_OF_FILE'
  1962. X#!/usr/local/bin/perl -s
  1963. X# testlock.pl -- test locking
  1964. X# SCCS Status     : @(#)@ testlock    1.1
  1965. X# Author          : Johan Vromans
  1966. X# Created On      : Thu Jun  4 21:22:45 1992
  1967. X# Last Modified By: Johan Vromans
  1968. X# Last Modified On: Sat Jun  6 20:55:39 1992
  1969. X# Update Count    : 64
  1970. X# Status          : 
  1971. X
  1972. X# Simpel testbed for mail server locking.
  1973. X#
  1974. X# To test, execute
  1975. X#
  1976. X#   % perl -s testlock.pl -test1 &
  1977. X#
  1978. X# It should say "Got the lock -- waiting ...".
  1979. X# Then execute
  1980. X#
  1981. X#   % perl -s testlock.pl -test2 &
  1982. X#
  1983. X# It should say "Good. Could not lock -- waiting ...".
  1984. X# Now kill the first process. The second process should print "ret = 1" 
  1985. X# and exit.
  1986. X
  1987. X$my_name = "testlock";
  1988. X$my_version = "1.1";
  1989. X#
  1990. X################ Common stuff ################
  1991. X
  1992. X$libdir = $ENV{"MSERVLIB"} || "/usr/local/lib/mserv";
  1993. Xunshift (@INC, $libdir);
  1994. Xrequire "mserv_common.pl";
  1995. X
  1996. X################ Main ################
  1997. X
  1998. X$tf = "/usr/tmp/f1lock";
  1999. X
  2000. Xif ( defined $test1 ) {
  2001. X
  2002. X    open ( F1, ">$tf");
  2003. X
  2004. X    local ($ret) =  &locking (*F1, 0);
  2005. X    if ( $ret == 1 ) {
  2006. X    print ("Got the lock -- waiting ...\n");
  2007. X    sleep 600;
  2008. X    close (F1);
  2009. X    unlink ($tf);
  2010. X    exit (0);
  2011. X    }
  2012. X
  2013. X    print ("Locking problem: ret = $ret [$!]\n");
  2014. X}
  2015. X
  2016. Xif ( defined $test2 ) {
  2017. X
  2018. X    open (F2, "+<$tf") || print ("Cannot open $tf [$!]\n");
  2019. X
  2020. X    local ($ret) = &locking (*F2, 0);
  2021. X    if ( $ret == 0 ) {
  2022. X    print ("Good, could not lock -- waiting ...\n");
  2023. X    $ret = &locking (*F2, 1);
  2024. X    print ("Ret = $ret\n");
  2025. X    close (F2);
  2026. X    unlink ($tf);
  2027. X    exit (0);
  2028. X    }
  2029. X
  2030. X    print ("Cannot lock exclusive: ret = $ret [$!]\n");
  2031. X    close (F2);
  2032. X}
  2033. END_OF_FILE
  2034.   if test 1542 -ne `wc -c <'testlock.pl'`; then
  2035.     echo shar: \"'testlock.pl'\" unpacked with wrong size!
  2036.   fi
  2037.   # end of 'testlock.pl'
  2038. fi
  2039. echo shar: End of archive 3 \(of 4\).
  2040. cp /dev/null ark3isdone
  2041. MISSING=""
  2042. for I in 1 2 3 4 ; do
  2043.     if test ! -f ark${I}isdone ; then
  2044.     MISSING="${MISSING} ${I}"
  2045.     fi
  2046. done
  2047. if test "${MISSING}" = "" ; then
  2048.     echo You have unpacked all 4 archives.
  2049.     rm -f ark[1-9]isdone
  2050. else
  2051.     echo You still must unpack the following archives:
  2052.     echo "        " ${MISSING}
  2053. fi
  2054. exit 0
  2055. exit 0 # Just in case...
  2056.